package com.xzy.urp.controller;


import com.xzy.urp.common.exception.Assert;
import com.xzy.urp.common.result.R;
import com.xzy.urp.common.result.ResponseEnum;
import com.xzy.urp.handle.TimingHandle;
import com.xzy.urp.pojo.vo.CourseSelectableVO;
import com.xzy.urp.pojo.vo.CourseTimeVO;
import com.xzy.urp.pojo.vo.StudentSelectVO;
import com.xzy.urp.service.CourseSelectionService;
import com.xzy.urp.service.CourseTimeService;
import com.xzy.urp.utils.JwtUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author xzy
 * @since 2022-02-17
 */
@RestController
@RequestMapping("/admin/courseSelection")
@Slf4j
@Api(tags = "选课相关接口")
public class CourseSelectionController {

//已选课程查询
//可选课程查询
//选课
//退课
//此接口含有并发操作，需要设置缓存及mq

    RedisTemplate<String, Object> template;

    CourseTimeService courseTimeService;

    CourseSelectionService courseSelectionService;

    public CourseSelectionController(RedisTemplate template,
                                     CourseTimeService courseTimeService,
                                     CourseSelectionService courseSelectionService) {
        this.template = template;
        this.courseTimeService = courseTimeService;
        this.courseSelectionService = courseSelectionService;
    }


    @ApiOperation("已选课程查询")
    @GetMapping("list/selected/{uid}/{year}")
    public R selectedCourse(@ApiParam("学生id") @PathVariable Long uid, @ApiParam("学年学期") @PathVariable Integer year
                           ) {
        List<CourseSelectableVO> selectedList = courseSelectionService.getSelectedList(year, uid);
        //先从redis中获取
        //若无则走数据库并存入redis

        return R.ok().message("获取成功").data("selectedList",selectedList);
    }
    @ApiOperation("可选课程查询")
    @PostMapping("list/selectable")
    public R optionalCourse(@ApiParam("查询对象") @RequestBody StudentSelectVO studentSelectVO) {
        //先从redis中获取
        //若无则走数据库并存入redis
        List<CourseSelectableVO> selectableList = courseSelectionService.getSelectableList(studentSelectVO);
        return R.ok().message("获取成功").data("selectableList",selectableList);
    }

    @ApiOperation("选课")
    @PostMapping("/task/choose/{cid}")
    public R select(@ApiParam("查询对象") @RequestBody StudentSelectVO studentSelectVO,
                    @ApiParam("课程号") @PathVariable Long cid)  {

        boolean flag = false;
        String key = "urp:core:select:lock:"+studentSelectVO.getUId();
        Long count = template.opsForValue().increment(key, 1);
        if(count == 1){//第一次请求
            try {
                flag = courseSelectionService.doSelect(studentSelectVO, cid);
            } catch (Exception e) {
               log.error(e.getMessage());
            }finally {
                //解锁
                template.delete(key);
            }
        }else if (count >1){
            Assert.isTrue(false, ResponseEnum.REPEAT_req);
        }


        if(flag){
            return R.ok().message("选课成功");
        }
        return  R.ok().message("选课失败");
    }



        @ApiOperation("退课")
        @PostMapping("/task/cancel/{cid}")
        public R cancel(@ApiParam("") @RequestBody StudentSelectVO studentSelectVO,
                @ApiParam("课程号") @PathVariable Long cid){

            boolean flag = false;
            String key = "urp:core:select:lock:"+studentSelectVO.getUId();
            Long count = template.opsForValue().increment(key, 1);
            if(count == 1){//第一次请求
                try {
                    flag = courseSelectionService.cancelSelect(studentSelectVO,cid);
                } catch (Exception e) {
                    log.error(e.getMessage());
                    e.printStackTrace();
                }finally {
                    //解锁
                    template.delete(key);
                }
            }else if (count >1){
                Assert.isTrue(false, ResponseEnum.REPEAT_req);
            }


            if(flag){
                return R.ok().message("退课成功");
            }
            return  R.ok().message("退课失败");


    }

    @ApiOperation("开启选课")
    @PostMapping("/optional/start")
    public R start(@ApiParam("专业") @RequestBody Integer semester) {
        //todo: 将所有可选课程课余量存入redis



        courseSelectionService.startOperation(semester);
        return R.ok();
    }

    @ApiOperation("结束选课")
    @PostMapping("/optional/over")
    public R over() {
        //todo: 清除此次选课阶段产生的所有缓存
        courseSelectionService.endOperation();
        return R.ok();
    }


}

